package com.stylefeng.guns.rest.modular.user;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.stylefeng.guns.api.user.UserAPI;
import com.stylefeng.guns.api.user.vo.*;
import com.stylefeng.guns.rest.common.CurrentUser;
import com.stylefeng.guns.rest.modular.vo.ResponseVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Base64Utils;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@Slf4j
@RequestMapping("/user/")
@RestController
public class UserController {

    @Reference(interfaceClass = UserAPI.class)
    private UserAPI userAPI;


    @RequestMapping(value="register",method = RequestMethod.POST)
    public ResponseVO register(UserModel userModel){
        if(userModel.getUsername() == null || userModel.getUsername().trim().length()==0){
            return ResponseVO.serviceFail("用户名不能为空");
        }
        if(userModel.getPassword() == null || userModel.getPassword().trim().length()==0){
            return ResponseVO.serviceFail("密码不能为空");
        }
        if(userModel.getNickname() == null || userModel.getNickname().trim().length()==0){
            return ResponseVO.serviceFail("昵称不能为空");
        }
        // 当返回true的时候，表示用户名可用
        boolean notExistsUsername = userAPI.checkUsername(userModel.getUsername());
        boolean notExistsNickname = userAPI.checkNickname(userModel.getNickname());
        if (notExistsUsername && notExistsNickname){
            boolean isSuccess = userAPI.register(userModel);
            if(isSuccess){
                return ResponseVO.success("注册成功");
            }else{
                return ResponseVO.serviceFail("注册失败");
            }
        }else{
            return ResponseVO.serviceFail("用户名或昵称已存在");
        }
    }

    @RequestMapping(value="checkUsername",method = RequestMethod.POST)
    public ResponseVO checkUsername(String username){
        if(username!=null && username.trim().length()>0){
            // 当返回true的时候，表示用户名可用
            boolean notExists = userAPI.checkUsername(username);
            if (notExists){
                return ResponseVO.success("用户名不存在");
            }else{
                return ResponseVO.serviceFail("用户名已存在");
            }

        }else{
            return ResponseVO.serviceFail("用户名不能为空");
        }
    }

    @RequestMapping(value="checkNickname",method = RequestMethod.POST)
    public ResponseVO checkNickname(String nickname){
        if(nickname!=null && nickname.trim().length()>0){
            // 当返回true的时候，表示昵称可用
            boolean notExists = userAPI.checkNickname(nickname);
            if (notExists){
                return ResponseVO.success("昵称不存在");
            }else{
                return ResponseVO.serviceFail("昵称已存在");
            }

        }else{
            return ResponseVO.serviceFail("昵称不能为空");
        }
    }


    @RequestMapping(value="logout",method = RequestMethod.GET)
    public ResponseVO logout(){
        /*
            应用：
                1、前端存储JWT 【七天】 ： JWT的刷新
                2、服务器端会存储活动用户信息【30分钟】
                3、JWT里的userId为key，查找活跃用户
            退出：
                1、前端删除掉JWT
                2、后端服务器删除活跃用户缓存
            现状：
                1、前端删除掉JWT
         */


        return ResponseVO.success("用户退出成功");
    }


    @RequestMapping(value="getUserInfo",method = RequestMethod.GET)
    public ResponseVO getUserInfo(){
        // 获取当前登陆用户
        String userId = CurrentUser.getCurrentUser();
        if(userId != null && userId.trim().length()>0){
            // 将用户ID传入后端进行查询
            int uuid = Integer.parseInt(userId);
            UserInfoModel userInfo = userAPI.getUserInfo(uuid);
            if(userInfo!=null){
                return ResponseVO.success(userInfo);
            }else{
                return ResponseVO.appFail("用户信息查询失败");
            }
        }else{
            return ResponseVO.serviceFail("用户未登陆");
        }
    }

    @RequestMapping(value="updateUserInfo",method = RequestMethod.POST)
    public ResponseVO updateUserInfo(UserInfoModel userInfoModel){
        // 获取当前登陆用户
        String userId = CurrentUser.getCurrentUser();
        if(userId != null && userId.trim().length()>0){
            // 将用户ID传入后端进行查询
            int uuid = Integer.parseInt(userId);
            // 判断当前登陆人员的ID与修改的结果ID是否一致
            if(uuid != userInfoModel.getUuid()){
                return ResponseVO.serviceFail("请修改您个人的信息");
            }

            UserInfoModel userInfo = userAPI.updateUserInfo(userInfoModel);
            if(userInfo!=null){
                return ResponseVO.success(userInfo);
            }else{
                return ResponseVO.appFail("用户信息修改失败");
            }
        }else{
            return ResponseVO.serviceFail("用户未登陆");
        }
    }

    /**
     * 实名认证接口
     * @param userValidRequestVO
     * @return
     */
    @PostMapping("userValid")
    @Transactional
    public ResponseVO userValid(UserValidRequestVO userValidRequestVO){
        // 获取当前登陆用户
        String userId = CurrentUser.getCurrentUser();
        if(userId != null && userId.trim().length()>0){
            //判断用户是否已完成过实名认证
            boolean isNotValid = userAPI.isNotValid(Integer.parseInt(userId));
            boolean validIdCard= userAPI.validIdCard(userValidRequestVO.getIdcard());
            if(!validIdCard){
                return ResponseVO.serviceFail("该身份已被认证过");
            }
            if(isNotValid){
                int uuid = Integer.parseInt(userId);
                Integer res = userAPI.authentication(uuid,userValidRequestVO);
                System.out.println(res);
                if(res == null || res <= 0){
                    return ResponseVO.serviceFail("实名认证失败了！");
                }else{
                    return ResponseVO.success("实名认证成功");
                }
            }else{
                return ResponseVO.serviceFail("你已经实名认证过了！无需重复认证。");
            }
        }else{
            return ResponseVO.serviceFail("用户未登陆");
        }
    }

    /**
     * 生成随机文件名：当前年月日时分秒+五位随机数
     *
     * @return
     */
    public String getRandomFileName() {

        SimpleDateFormat simpleDateFormat;

        simpleDateFormat = new SimpleDateFormat("yyyyMMdd");

        Date date = new Date();

        String str = simpleDateFormat.format(date);

        Random random = new Random();

        int rannum = (int) (random.nextDouble() * (99999 - 10000 + 1)) + 10000;// 获取5位随机数

        return rannum + str;// 当前时间
    }

    /**
     * 单文件上传
     * @param file
     * @return
     * @throws IOException
     */
    @PostMapping("/uploadFile")
    public ResponseVO uploadFile(@RequestParam("file") MultipartFile file) throws IOException {
        // 获取当前登陆用户
        String userId = CurrentUser.getCurrentUser();
        userId="1";
        if(userId == null || userId.trim().length() <= 0){
            return ResponseVO.serviceFail("请先登录");
        }
        String path = "/var/www/html/product/head/";
//        String path = "/var/www/html/product/head";
        String fileName = file.getOriginalFilename();
        String suffix  = fileName.substring(fileName.lastIndexOf(".")+1);
        String newFileName = getRandomFileName()+"."+suffix;
        String headAddr = path + newFileName;
        file.transferTo(new File( headAddr));
        headAddr = "http://47.100.244.66/product/head/"+newFileName;
        UserInfoModel userInfoModel = new UserInfoModel();
        userInfoModel.setUuid(Integer.parseInt(userId));
        userInfoModel.setHeadAddr(headAddr);
        UserInfoModel userInfo = userAPI.updateUserInfo(userInfoModel);
        return ResponseVO.success(userInfo);
    }

    /**
     * 多文件上传
     * @param files
     * @return
     * @throws IOException
     */
    @PostMapping("/uploadFiles")
    public ResponseVO uploadFiles(@RequestParam("file") MultipartFile[] files) throws IOException {
        // 获取当前登陆用户
        String userId = CurrentUser.getCurrentUser();
        if(userId == null || userId.trim().length() <= 0){
            return ResponseVO.serviceFail("请先登录");
        }
        String path = "/var/www/html/product/head/";
        if (files == null || files.length == 0) {
            return ResponseVO.serviceFail("请选择文件");
        }
        List<UserInfoModel> userInfoModelList = new ArrayList<>();
        for (MultipartFile file : files) {
            String fileName = file.getOriginalFilename();
            String suffix  = fileName.substring(fileName.lastIndexOf(".")+1);
            String headAddr = path + getRandomFileName()+"."+suffix;
            // TODO Spring Mvc 提供的写入方式
            file.transferTo(new File(headAddr));
            headAddr = "http://47.100.244.66/product/head/"+fileName;
            UserInfoModel userInfoModel = new UserInfoModel();
            userInfoModel.setUuid(Integer.parseInt(userId));
            userInfoModel.setHeadAddr(headAddr);
            UserInfoModel userInfo = userAPI.updateUserInfo(userInfoModel);
            userInfoModelList.add(userInfo);
        }
        return ResponseVO.success(userInfoModelList);
    }

    @PostMapping("/uploadByAZ")
    public ResponseVO uploadByAZ(String base64) throws IOException {
        // 获取当前登陆用户
        String userId = CurrentUser.getCurrentUser();
        if(userId == null || userId.trim().length() <= 0){
            return ResponseVO.serviceFail("请先登录");
        }
        String path = "/var/www/html/product/head/";
//        String path = "C:\\Users\\Administrator\\Desktop\\qrcode\\video";
        String[] d = base64.split(";base64,");
        String suffix  = d[0].split("/")[1];
        String fileName = getRandomFileName()+"."+suffix;
        String headAddr = path+fileName;
        // TODO BASE64 方式的 格式和名字需要自己控制（如 png 图片编码后前缀就会是 data:image/png;base64,）
        final File tempFile = new File(headAddr);
        headAddr = "http://47.100.244.66/product/head/"+fileName;
        // TODO 防止有的传了 data:image/png;base64, 有的没传的情况
        final byte[] bytes = Base64Utils.decodeFromString(d.length > 1 ? d[1] : d[0]);
        FileCopyUtils.copy(bytes, tempFile);
        UserInfoModel userInfoModel = new UserInfoModel();
        userInfoModel.setUuid(Integer.parseInt(userId));
        userInfoModel.setHeadAddr(headAddr);
        UserInfoModel userInfo = userAPI.updateUserInfo(userInfoModel);
        if(userInfo == null){
            return ResponseVO.serviceFail("上传头像失败！");
        }
        return ResponseVO.success(userInfo);
    }

    /**
     * 获取浏览记录
     * @return
     */
    @GetMapping(value = "getHistory")
    public ResponseVO getHistory(){
        // 获取当前登陆用户
        String userId = CurrentUser.getCurrentUser();
        int uid = Integer.parseInt(userId);
        if(uid<=0){
            return ResponseVO.serviceFail("请先登录");
        }
        Map historys = userAPI.getHistorys(uid);
        return ResponseVO.success(historys);
    }

    /**
     * 添加浏览记录
     * @param content
     * @param picPath
     * @param uid
     * @param livePath
     * @param cid
     * @return
     */
    @PostMapping(value = "addHistory")
    public ResponseVO addHistory(@RequestParam(value = "content",required = true)String content,
                                 @RequestParam(value = "pic_path",required = true)String picPath,
                                 @RequestParam(value = "user_id",required = true)String uid,
                                 @RequestParam(value = "live_path",required = true)String livePath,
                                 @RequestParam(value = "type",required = true)Integer cid,
                                 @RequestParam(value = "room_id",required = true)String guid){
        int i = userAPI.addHistory(content, picPath, uid, livePath, cid,guid);
        if(i<=0){
            return ResponseVO.serviceFail("记录添加失败");
        }
        return ResponseVO.success("记录成功");
    }

    /**
     * 点击关注
     * @param fromUserId
     * @param toUserId
     * @return
     */
    @GetMapping(value = "toFocus")
    public ResponseVO toFocus(@RequestParam(value = "from_user_id")Integer fromUserId,
                              @RequestParam(value = "to_user_id")Integer toUserId){
        int i = userAPI.toFocus(fromUserId, toUserId);
        if(i<=0){
            return ResponseVO.serviceFail("关注失败，请检查网络");
        }
        return ResponseVO.success("关注成功");
    }

    /**
     * 查看个人信息
     * @return
     * @throws ParseException
     */
    @GetMapping(value = "getUserDetail")
    public ResponseVO getUserDetail(@RequestParam(value = "user_id",required = true) int uid) throws ParseException {
        UserDetailInfo userDetail = userAPI.getUserDetail(uid);
        if(userDetail==null){
            return ResponseVO.serviceFail("网络异常");
        }
        return ResponseVO.success(userDetail);
    }

    /**
     * 更新个人信息
     * @param base64
     * @param nickname
     * @return
     * @throws IOException
     */
    @PostMapping(value = "updateUserDetail")
    public ResponseVO updateUserDetail(@RequestParam(value = "base64",required = false)String base64,
                                       @RequestParam(value = "nickname",required = false)String nickname) throws IOException {
        // 获取当前登陆用户
        String userId = CurrentUser.getCurrentUser();
        if(userId == null || userId.trim().length() <= 0){
            return ResponseVO.serviceFail("请先登录");
        }
        UserInfoModel userInfoModel = new UserInfoModel();
        if(base64 != null){
            String headAddr = upload(base64);
            userInfoModel.setHeadAddr(headAddr);
        }
        if(nickname != null){
            userInfoModel.setNickname(nickname);
        }
        userInfoModel.setUuid(Integer.parseInt(userId));
        UserInfoModel userInfoModel1 = userAPI.updateUserInfo(userInfoModel);
        return ResponseVO.success(userInfoModel1);
    }

    private String upload(String base64) throws IOException {
        String path = "/var/www/html/product/head/";
//        String path = "C:\\Users\\Administrator\\Desktop\\qrcode\\video";
        String[] d = base64.split(";base64,");
        String suffix  = d[0].split("/")[1];
        String fileName = getRandomFileName()+"."+suffix;
        String headAddr = path+fileName;
        // TODO BASE64 方式的 格式和名字需要自己控制（如 png 图片编码后前缀就会是 data:image/png;base64,）
        final File tempFile = new File(headAddr);
        headAddr = "http://47.100.244.66/product/head/"+fileName;
        // TODO 防止有的传了 data:image/png;base64, 有的没传的情况
        final byte[] bytes = Base64Utils.decodeFromString(d.length > 1 ? d[1] : d[0]);
        FileCopyUtils.copy(bytes, tempFile);
        return headAddr;
    }

    /**
     * 获取任务和活动
     * @return
     */
    @GetMapping(value = "getJobs")
    @Transactional
    public ResponseVO getJobs(){
        // 获取当前登陆用户
        String userId = CurrentUser.getCurrentUser();
        if(userId == null || userId.trim().length() <= 0){
            return ResponseVO.serviceFail("请先登录");
        }
        //获取任务id列表
        List<Integer> jobIds = userAPI.getJobIds();
        //统计任务数
        Integer count = jobIds.size();
//        Integer countJobDetail = userAPI.countJobDetail(Integer.parseInt(userId));
        if(count > 0){
            for(Integer jobId:jobIds){
                //批量添加
                userAPI.toJoin(Integer.parseInt(userId),jobId);
            }
        }
        JobVO jobs = userAPI.getJobs(Integer.parseInt(userId));

        return ResponseVO.success(jobs);
    }

    /**
     * 点击报名
     * @param jobId
     * @return
     */
    @GetMapping(value = "toJoin")
    public ResponseVO toJoin(@RequestParam(value = "job_id",required = true)Integer jobId){
        // 获取当前登陆用户
        String userId = CurrentUser.getCurrentUser();
        if(userId == null || userId.trim().length() <= 0){
            return ResponseVO.serviceFail("请先登录");
        }
        int i = userAPI.toJoin(Integer.parseInt(userId), jobId);
        if(i<=0){
            return ResponseVO.serviceFail("报名失败");
        }
        return ResponseVO.success("报名成功");
    }

    /**
     * 取消关注
     * @param fromUserId
     * @param toUserId
     * @return
     */
    @PostMapping(value = "delFocus")
    public ResponseVO delFoucs(@RequestParam(value = "from_user_id")Integer fromUserId,
                               @RequestParam(value = "to_user_id")Integer toUserId){
        int i = userAPI.delFoucs(fromUserId, toUserId);
        if(i<=0){
            return ResponseVO.serviceFail("取消关注失败，请检查网络");
        }
        return ResponseVO.success("取消关注成功");
    }
    /**
     * 添加已完成任务量
     * @return
     */
    @GetMapping(value = "addHadDone")
    public ResponseVO addHadDone(){
        // 获取当前登陆用户
        String userId = CurrentUser.getCurrentUser();
        if(userId == null || userId.trim().length() <= 0){
            return ResponseVO.serviceFail("请先登录");
        }
        return null;
    }


}
